<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <input-number :max="100" :min="0" :value="value" @modify="modifyValue"></input-number>
        <p>value:{{ value }}</p>
    </div>

    <template id="temp">
        <div>
            <button @click="decrease">-</button>
            <input type="number" :value="value" @input="setValue">
            <button @click="increase">+</button>
        </div>
    </template>

    <script>
        Vue.component("input-number", {
            template: "#temp",
            props: {
                max: {
                    type: Number,
                    default: Infinity 
                },
                min: {
                    type: Number,
                    default: -Infinity
                },
                value: {
                    type: Number,
                    default: 0
                }
            },
            methods: {
                decrease() {
                    this.$emit("modify", this.value-1)
                },
                increase() {
                    this.$emit("modify", this.value+1)
                },
                setValue(even) {
                    this.$emit("modify", Number(even.target.value))
                }
            },
            watch: {
                value(newValue) {
                    if(newValue > this.max) {
                        newValue = this.max
                    } else if(newValue < this.min) {
                        newValue = this.min
                    }
                    this.$emit("modify", newValue)
                    this.value = newValue
                }
            }
        })

        new Vue({
            el: "#app",
            data: {
                value: 15
            },
            methods: {
                modifyValue(newValue) {
                    this.value = newValue
                }
            }
        })
    </script>
</body>
</html>